/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.x.component.connectivity;

import android.annotation.SuppressLint;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import com.x.component.connectivity.SignalIcon.IconGroup;

/**
 * Base type for various connectivity states, for use with SignalController and its subtypes
 */
public class ConnectivityState {
    public boolean connected = false;
    public boolean enabled = false;
    public boolean activityIn = false;
    public boolean activityOut = false;
    public int level = 0;
    public IconGroup iconGroup = null;
    public int inetCondition = 0;
    // Only for logging.
    public int rssi = 0;
    // Not used for comparison, just used for logging.
    public long time = 0;

    @Override
    public String toString() {
        if (time != 0L) {
            StringBuilder builder = new StringBuilder();
            toString(builder);
            return builder.toString();
        } else {
            return "Empty " + getClass().getSimpleName();
        }
    }

    protected List<String> tableColumns() {
        return Arrays.asList(
                "connected",
                "enabled",
                "activityIn",
                "activityOut",
                "level",
                "iconGroup",
                "inetCondition",
                "rssi",
                "time");
    }

    protected List<String> tableData() {
        return Arrays.asList(
                String.valueOf(connected),
                String.valueOf(enabled),
                String.valueOf(activityIn),
                String.valueOf(activityOut),
                String.valueOf(level),
                String.valueOf(iconGroup),
                String.valueOf(inetCondition),
                String.valueOf(rssi),
                sSDF.format(time));
    }

    protected void copyFrom(ConnectivityState other) {
        connected = other.connected;
        enabled = other.enabled;
        activityIn = other.activityIn;
        activityOut = other.activityOut;
        level = other.level;
        iconGroup = other.iconGroup;
        inetCondition = other.inetCondition;
        rssi = other.rssi;
        time = other.time;
    }

    protected void toString(StringBuilder builder) {
        builder.append("connected=").append(connected).append(",")
               .append("enabled=").append(enabled).append(",")
               .append("level=").append(level).append(",")
               .append("inetCondition=").append(inetCondition).append(",")
               .append("iconGroup=").append(iconGroup).append(",")
               .append("activityIn=").append(activityIn).append(",")
               .append("activityOut=").append(activityOut).append(",")
               .append("rssi=").append(rssi).append(",")
               .append("lastModified=").append(sSDF.format(time));
    }

    @Override
    public boolean equals(Object other) {
        if (this == other) return true;
        if (other == null || getClass() != other.getClass()) return false;
        if (!super.equals(other)) return false;

        ConnectivityState that = (ConnectivityState) other;
        return connected == that.connected &&
                enabled == that.enabled &&
                activityIn == that.activityIn &&
                activityOut == that.activityOut &&
                level == that.level &&
                inetCondition == that.inetCondition &&
                Objects.equals(iconGroup, that.iconGroup) &&
                rssi == that.rssi &&
                time == that.time;
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), connected, enabled, activityIn, activityOut, level, iconGroup, inetCondition, rssi, time);
    }

    // No locale as it's only used for logging purposes
    @SuppressLint("SimpleDateFormat")
    private static final SimpleDateFormat sSDF = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
}
